using System;
using System.Collections.Generic;
using System.Text;

namespace SharpMud.MudLib.NovaSMAUG.Interop
{
    public static class Text
    {

        /// <summary>
        /// Converts a null-terminated array of characters into a string
        /// </summary>
        public static string NormalizeToString(char[] characterArray)
        {
            return NormalizeToString(ArrayIndexPointer<char>.Create(characterArray), characterArray.Length);
        }

        /// <summary>
        /// Collects a null-terminated array of characters from the given pointer into a string
        /// </summary>
        public static string NormalizeToString(ArrayIndexPointer<char> charPointer)
        {
            return NormalizeToString(charPointer, int.MaxValue);
        }

        /// <summary>
        /// Collects a null-terminated array of characters from the given pointer into a string
        /// </summary>
        public static string NormalizeToString(ArrayIndexPointer<char> charPointer, int maxLength)
        {
            ArrayIndexPointer<char> c = charPointer.Clone();
            System.Text.StringBuilder sb = new StringBuilder();
            int maxIndex = c.Index + maxLength;
            char ch;
            for (; (c.Index < maxIndex); c.Index++)
            {
                try
                {
                    ch = c.Value;
                }
                catch (IndexOutOfRangeException e)
                {
                    ch = '\0';
                }
                if (ch == '\0')
                    break;
                sb.Append(ch);
            }
            return sb.ToString();
        }

        [Obsolete("Present for compatibility purposes only.", false)]
        public static bool isspace(char value)
        {
            if (char.IsWhiteSpace(value))
                return true;
            else
                return false;

        }

        [Obsolete("Present for compatibility purposes only.", false)]
        public static bool isdigit(char value)
        {
            if (char.IsDigit(value))
                return true;
            else
                return false;
        }

        [Obsolete("Present for compatibility purposes only.", false)]
        public static bool isspace(ArrayIndexPointer<char> value)
        {
            return isspace(value.Value);
        }

        /// <summary>
        /// Removes the tildes from a string. Used for player-entered strings that go into disk files.
        /// </summary>
        /// <remarks>Replaces tildes ( '~' ) with hyphens ( '-' ).</remarks>
        public static string smash_tilde(ref string str)
        {
            return (str = str.Replace(Constants.Tilde, Constants.SmashedTilde));
        }

        /// <summary>
        /// Encodes the tildes in a string. Used for player-entered strings that go into disk files.
        /// </summary>
        /// <credits>Thoric</credits>
        public static string hide_tilde(ref string str)
        {
            return (str = str.Replace(Constants.Tilde, Constants.HiddenTilde));
        }

        public static string show_tilde(ref string str)
        {
            return (str = str.Replace(Constants.HiddenTilde, Constants.Tilde));
        }

        /// <summary>
        /// Compare strings, case insensitive.
        /// </summary>
        /// <returns>Return TRUE if different - (compatibility with historical functions).</returns>
        [Obsolete("Present for compatibility purposes only.", false)]
        public static bool str_cmp(string astr, string bstr)
        {
            if (astr == null) throw new ArgumentNullException("astr");
            if (bstr == null) throw new ArgumentNullException("bstr");

            if (astr.ToLower().CompareTo(bstr.ToLower()) == 0)
                return false;
            else
                return true;
        }

        /// <summary>
        /// Compare strings, case insensitive.
        /// </summary>
        /// <returns>Return TRUE if different - (compatibility with historical functions).</returns>
        [Obsolete("Present for compatibility purposes only.", false)]
        public static bool str_cmp(char[] astr, string bstr)
        {
            return str_cmp(NormalizeToString(astr), bstr);
        }

        /// <summary>
        /// Compare strings, case insensitive, for prefix matching.
        /// </summary>
        /// <returns>Return TRUE if astr not a prefix of bstr (compatibility with historical functions).</returns>
        [Obsolete("Present for compatibility purposes only.", false)]
        public static bool str_prefix(string astr, string bstr)
        {
            if (bstr.ToLower().StartsWith(astr.ToLower()))
                return false;
            else
                return true;
        }

        /// <summary>
        /// Compare strings, case insensitive, for match anywhere.
        /// </summary>
        /// <returns>Returns TRUE is astr not part of bstr. (compatibility with historical functions).</returns>
        [Obsolete("Present for compatibility purposes only.", false)]
        public static bool str_infix(string astr, string bstr)
        {
            if (bstr.ToLower().IndexOf(astr.ToLower()) >= 0)
                return false;
            else
                return true;
        }

        /// <summary>
        /// Compare strings, case insensitive, for suffix matching.
        /// </summary>
        /// <returns>Return TRUE if astr not a suffix of bstr (compatibility with historical functions).</returns>
        [Obsolete("Present for compatibility purposes only.", false)]
        public static bool str_suffix(string astr, string bstr)
        {
            if (bstr.ToLower().EndsWith(astr.ToLower()))
                return false;
            else
                return true;
        }

        /// <summary>
        /// Returns an initial-capped string.
        /// </summary>
        public static string capitalize(string str)
        {
            return str.Substring(0, 1).ToUpper() + str.Substring(1).ToLower();
        }

        [Obsolete("Present for compatibility purposes only.", false)]
        /// <summary>Returns a lowercase string.</summary>
        public static string strlower(string str)
        {
            return str.ToLower();
        }


        [Obsolete("Present for compatibility purposes only.", false)]
        /// <summary>Returns an uppercase string.</summary>
        public static string strupper(string str)
        {
            return str.ToUpper();
        }

        /// <summary>
        /// Determines if the letter is a vowel
        /// </summary>
        /// <returns>True if the letter is a vowel, otherwise False.</returns>
        /// <credits>Thoric</credits>
        public static bool isavowel(char letter)
        {
            char c;

            c = Char.ToLower(letter);
            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
                return true;
            else
                return false;
        }

        /// <summary>
        /// Shove either "a " or "an " onto the beginning of a string
        /// </summary>
        /// <credits>Thoric</credits>
        public static string aoran(string str)
        {
            if (str == null)
                throw new ArgumentNullException("str");
            string s = str.TrimStart();
            if (s == String.Empty)
                throw new ArgumentException("Cannot affix 'a' or 'an' onto an empty string!");

            if (isavowel(s[0]) || ((s.Length > 1) && (Char.ToLower(s[0]) == 'y' && !isavowel(s[1]))))
            {
                return "an " + s;
            }
            else
            {
                return "a " + s;
            }
        }

    }
}